package autoz.czt.visitor;

import java.util.ArrayList;
import java.util.List;

import net.sourceforge.czt.base.ast.Term;
import net.sourceforge.czt.base.visitor.TermVisitor;
import net.sourceforge.czt.base.visitor.VisitorUtils;
import net.sourceforge.czt.session.CommandException;
import net.sourceforge.czt.session.SectionManager;
import net.sourceforge.czt.typecheck.z.ErrorAnn;
import net.sourceforge.czt.z.ast.Para;
import net.sourceforge.czt.z.ast.Spec;
import net.sourceforge.czt.z.ast.ZName;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.Path;

import autoz.core.markers.MarkerManager;
import autoz.core.problems.UmlProblem;

public class ErrorVisitor implements TermVisitor<Object> {
	
	public static void main(String[] args){
		String file = "/local/d0p6/jw/Projects/autoz/autoz.czt/tex/simple.tex";
//		String file = "/Users/jimmy/Documents/Projects/autozmarkii/autoz.czt/tex/simple.tex";
		IFile iFile = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(file));
		
		SectionManager manager = new SectionManager();
		Spec spec;
		List<? extends ErrorAnn> errors = new ArrayList<ErrorAnn>();
		try {
			spec = CZTUtils.parseSpec(file, manager);
			errors = CZTUtils.typecheck(spec, manager);
			
			if (errors.size() > 0){
				System.out.println("Typecheck errors:");
				for (ErrorAnn ae : errors){
					System.out.println(ae);
				}
			} else{
				System.out.println("No errors found.");
			}
			
			
			ErrorVisitor v = new ErrorVisitor();
			spec.accept(v);
			
			List<UmlProblem> errs = v.getErrors();
			
			for(UmlProblem e : errs){
				System.out.println(e);
			}
			
			for (String s : v.testList){
				System.out.println(s);
			}
			
			
			MarkerManager markermanager;
			
			if (iFile != null){
				markermanager = new MarkerManager(iFile);
				try {
					markermanager.replaceErrorMarkers(errs);
					System.out.println("Markers should have appeared");
				} catch (CoreException e) {
					e.printStackTrace();
				}
			}else{
				System.out.println("Resource was null");
			}
			
			
			
		} catch (CommandException e1) {
			e1.printStackTrace();
		}
	}
	
	
	private List<UmlProblem> errorList = new ArrayList<UmlProblem>();
	private List<String> testList = new ArrayList<String>();

	public ErrorVisitor() {
	}

	public List<UmlProblem> getErrors() {
		return errorList;
	}

	boolean foundSchema = false;
	String foundSchemaName = "";
	
	/**
	 * In order to match errors found, to the schema that the error was found in
	 */
	public Object visitTerm(Term term) {
//		System.out.println(term.getClass());
		
		if (term instanceof Para){
			foundSchema = true;
		} else if(foundSchema && term instanceof ZName){
			foundSchemaName = ((ZName)term).getWord();
			foundSchema = false;
		} else if (term instanceof ZName){
			testList.add("name:"+((ZName)term).getWord() + ", schema:"+ foundSchemaName);
		}
		
		for(Object ann : term.getAnns()){
			if (ann instanceof ErrorAnn){
				errorList.add(new UmlProblem(((ErrorAnn)ann).getMessage(), foundSchemaName, ((ErrorAnn) ann).getLine()));
			}
		}
		VisitorUtils.visitTerm(this, term);
		return null;
	}
}
